package com.topisv.tms.service;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.hibernate.ejb.criteria.predicate.ComparisonPredicate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.mapper.BeanMapper;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;
import org.springside.modules.persistence.SearchFilter.Operator;

import com.topisv.tms.entity.BackupTask;
import com.topisv.tms.entity.BackupTaskOrdeno;
import com.topisv.tms.entity.BackupTaskSku;
import com.topisv.tms.entity.BatchTask;
import com.topisv.tms.entity.CusStockMerge;
import com.topisv.tms.entity.Customers;
import com.topisv.tms.entity.EdiGoodsSku;
import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.entity.EdiOrderItem;
import com.topisv.tms.entity.Role;
import com.topisv.tms.entity.ShippedBatch;
import com.topisv.tms.entity.ShippedBox;
import com.topisv.tms.entity.ShippedBoxOrdeno;
import com.topisv.tms.entity.ShippedBoxSkus;
import com.topisv.tms.entity.User;
import com.topisv.tms.entity.dto.BackupTaskSkuDTO;
import com.topisv.tms.entity.log.OrderLog;
import com.topisv.tms.entity.stock.CusStock;
import com.topisv.tms.entity.work.WorkLog;
import com.topisv.tms.entity.work.WorkTaskItem;
import com.topisv.tms.repository.BackupTaskDao;
import com.topisv.tms.repository.BackupTaskOrdenoDao;
import com.topisv.tms.repository.BackupTaskSkuDao;
import com.topisv.tms.repository.BatchTaskDao;
import com.topisv.tms.repository.CusStockMergeDao;
import com.topisv.tms.repository.CustomersDao;
import com.topisv.tms.repository.EdiGoodsSkuDao;
import com.topisv.tms.repository.EdiOrderDao;
import com.topisv.tms.repository.EdiOrderItemDao;
import com.topisv.tms.repository.RoleDao;
import com.topisv.tms.repository.ShippedBatchDao;
import com.topisv.tms.repository.ShippedBoxDao;
import com.topisv.tms.repository.ShippedBoxOrdenoDao;
import com.topisv.tms.repository.ShippedBoxSkusDao;
import com.topisv.tms.repository.UserDao;
import com.topisv.tms.repository.log.OrderLogDao;
import com.topisv.tms.repository.stock.CusStockDao;
import com.topisv.tms.repository.work.WorkLogDao;
import com.topisv.tms.repository.work.WorkTaskItemDao;
import com.topisv.tms.service.account.ShiroDbRealm.ShiroUser;
import com.topisv.tms.service.vo.StockSku;
import com.topisv.tms.utils.BackupTaskRule;
import com.topisv.tms.utils.enums.StatusEnums;
import com.topisv.tms.web.dto.GroupBackupTaskDTO;
import com.topisv.tms.web.dto.PrintEdiOrdeno;
import com.topisv.tms.web.dto.PrintEdiOrdenoItem;
import com.topisv.tms.web.dto.UserDTO;

//Spring Bean的标识.
@Component
// 默认将类中的所有public函数纳入事务管理.
@Transactional(readOnly = true)
public class BackupTaskService {

	private static final Logger log = LoggerFactory.getLogger(BackupTaskService.class);
	
	@Autowired
	private BackupTaskDao backupTaskDao;
	@Autowired
	private EdiOrderItemDao ediOrderItemDao;
	@Autowired
	private BackupTaskSkuDao backupTaskSkuDao;
	@Autowired
	private BackupTaskOrdenoDao backupTaskOrdenoDao;
	@Autowired
	private EdiOrderDao ediOrderDao;
	@Autowired
	private ShippedBatchDao shippedBatchDao;
	@Autowired
	private BatchTaskDao batchTaskDao;
	@Autowired
	private UserDao userDao;
	@Autowired
	private RoleDao roleDao;
	@Autowired
	private ShippedBoxOrdenoDao shippedBoxOrdenoDao;
	@Autowired
    private EdiGoodsSkuDao ediGoodsSkuDao;

	@Autowired
	private CustomersDao customersDao;
	@Autowired
	private WorkTaskItemDao workTaskItemDao;
	@Autowired
	private CusStockDao cusStockDao;
	@Autowired
	private WorkLogDao workLogDao;
	@Autowired
	private OrderLogDao orderLogDao;
	@Autowired
	private ShippedBoxSkusDao shippedBoxSkusDao;
	@Autowired
	private ShippedBoxDao shippedBoxDao;
	@Autowired
	private CusStockMergeDao cusStockMergeDao;
	
	@Transactional(readOnly = false)
	public BackupTask setJobuuid(String backupTaskCode,String jobuuid,String pickType){
		BackupTask backupTask=this.backupTaskDao.findByBackupTaskCode(backupTaskCode);
		if("pending".equals(backupTask.getPickType())){//判断拣货类型
			backupTask.setPickType(pickType);
		}else if(!pickType.equals(backupTask.getPickType())){
			return null;
		}
		ShippedBatch shippedBatch=this.shippedBatchDao.findByBackupTaskCode(backupTaskCode);
		if(backupTask.getJobuuid()==null||"pending".equals(backupTask.getJobuuid())){
			backupTask.setJobuuid(jobuuid);
			this.backupTaskDao.save(backupTask);
		}else{
			if(!jobuuid.equals(backupTask.getJobuuid())){
				return null;
			}
		}
		if(shippedBatch.getJobuuid()==null||"pending".equals(shippedBatch.getJobuuid())){
			shippedBatch.setJobuuid(jobuuid);
			this.shippedBatchDao.save(shippedBatch);
		}
		backupTask.setBoxQty(shippedBatch.getBoxQty());
		return backupTask;
	}
	
	@Transactional(readOnly = false, rollbackFor = Exception.class)
    private void updateStock(BackupTask task) throws Exception {
		try {
			List<BackupTaskOrdeno> orderList=this.backupTaskOrdenoDao.findByBackupTaskCode(task.getBackupTaskCode());
			String customerCode=task.getCustomerCode();
			String warehouseCode=task.getWarehouseCode();
			String stockInfo,stockCode,boxCode,sku;
			Integer num;
			String[] stockInfoSplit;
			String[] infoSplit;
			CusStock stock;
			for (BackupTaskOrdeno workOrder : orderList) {
				stockInfo=workOrder.getStockInfo();
				stockInfoSplit=stockInfo.split(";");
				for (String info : stockInfoSplit) {
					infoSplit=info.split("_");
					stockCode=infoSplit[0];
					boxCode=infoSplit[1];
					sku=infoSplit[2];
					num=Integer.valueOf( infoSplit[3] );
					stock=this.cusStockDao.loadStock(customerCode, warehouseCode, stockCode, boxCode, sku);
					if(stock.getOrderNum() - num < 0){//add by LiBin 20160808
	                    throw new Exception("订单占用库存异常：stockCode:"+stockCode+" sku:" + sku);
	                }
					stock.setOrderNum(stock.getOrderNum()-num);
					this.cusStockDao.save(stock);
				}
			}
		} catch (Exception e) {
			throw e;
		}
	}

	
	/**
	 * 完成拣货任务
	 * @param taskId
	 * @throws Exception
	 */
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void completePickTask(Long taskId) throws Exception {
		try {
			Date now=new Date();
			ShiroUser curUser = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
			User user=this.userDao.findByJobuuid(curUser.jobuuid);
			
			//修改任务状态
			BackupTask task=this.backupTaskDao.findOne(taskId);
			task.setStatus(""); //任务状态( 1.创建任务 2.已分配拣货任务  3.已拣货  4. 已分配灯光拣选任务  5.已经灯光拣选  6.已分配包装任务  7.已包装  8.已分配发货任务  9.已发货  10.灯光拣选进行中.. 11.推车拣选进行中..)
			this.backupTaskDao.save(task);
			//添加作业日志
			WorkLog workLog=new WorkLog(
					task.getBatchCode(),
					"4",//操作类型 (1.创建批次 2.创建任务 3.领取拣货任务  4.完成拣货任务 5.领取灯光拣选任务 6.完成灯光拣选任务  7.领取包装任务 8完成包装任务  9.领取发货任务  10.完成发货任务   )
					user.getRealname()+"完成拣货任务（"+task.getBackupTaskCode()+"）", 
					now, 
					user);
			this.workLogDao.save(workLog);
			
			//修改库存状态：从订单占用状态减去
			Customers customer=this.customersDao.findByCustomerCode(task.getCustomerCode());
			if("1".equals(customer.getSubStock())){
				this.updateStock(task);//修改订单占用库存
			}
			
			//修改订单状态，添加日志
			List<BackupTaskOrdeno> orderList=this.backupTaskOrdenoDao.findByBackupTaskCode(task.getBackupTaskCode());
			List<OrderLog> logList=new ArrayList<OrderLog>();
			for (BackupTaskOrdeno order : orderList) {
				
				OrderLog log=new OrderLog(
						order.getOrdeno(),
						task.getCustomerCode(),
						"3", //操作类型 （1.创建批次 2.创建任务  3.拣货完成 4.包装完成 5.发货完成 6.签收完成 7.异常登记 8.完成灯光拣选任务 9.打印单据）
						user,
						now,
						null,
						user.getRealname()+"完成拣货");
				logList.add(log);
				
				order.setStatus("9"); //订单状态 (1.创建批次 2.创建任务 3.已拣货  4.已灯光拣选  9.待包装   5.已包装  6.已发货  7.已签收  8.异常 )
			}
			
			this.backupTaskOrdenoDao.save(orderList);
			this.orderLogDao.save(logList);
			
			//查看同一批次的其他任务是否完成，如果都完成，修改入库批次状态为：3
			List<BackupTask> uncompletedTaskList=this.backupTaskDao.findByBatchCode(task.getBatchTaskCode());
			if(uncompletedTaskList==null || uncompletedTaskList.size()==0){
				BatchTask batch=this.batchTaskDao.findByBatchTaskCode(task.getBatchTaskCode());
				batch.setStatus("3"); //批次状态 (1.已创建批次 2.已创建任务 3.已拣货  4.已包装  5.已发货)
				this.batchTaskDao.save(batch);
				
				//添加工作日志
				WorkLog workLog1=new WorkLog(
						task.getBatchCode(),
						"4",//操作类型 (1.创建批次 2.创建任务 3.领取拣货任务  4.完成拣货任务 5.领取灯光拣选任务 6.完成灯光拣选任务  7.领取包装任务 8完成包装任务  9.领取发货任务  10.完成发货任务   )
						"拣货任务全部完成", 
						now, 
						null);
				this.workLogDao.save(workLog1);
			}
			
			
		} catch (Exception e) {
			throw new Exception(e);
		}
	}
	
	
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public  void pickBackupTaskSku(String backupTaskCode, String sku) throws Exception {
		int number=1;
		boolean fa=false;
		List<ShippedBoxSkus> shippedBoxSkusLists = null;
		BackupTask backupTask = null;
		BackupTaskSku backupTaskSku =null;
		ShippedBoxSkus shippedBoxSkus=null;
		try {
			backupTask = backupTaskDao.findByBackupTaskCode(backupTaskCode);
			if (backupTask == null) {
				return ;
			}
			backupTaskSku = backupTaskSkuDao.findByBackupTaskCodeAndSkuId(backupTaskCode, sku);
			if (backupTaskSku == null) {
				return ;
			}
			if("finish".equals(backupTaskSku.getPickStatus())){
				return;
			}
			if ("finish".equals(backupTask.getPickStatus())) {
				return ;
			}
			if ("finish".equals(backupTask.getStatus())) {
				return ;
			}
			int indexNumber = number + backupTaskSku.getPickQty();
			if (indexNumber > backupTaskSku.getRealQty()) {
				return ;
			}
			if(indexNumber==backupTaskSku.getRealQty()){
				backupTaskSku.setPickStatus("finish");
			}
			//根据拣货任务号查找商品是否装箱
			shippedBoxSkusLists = shippedBoxSkusDao.findByBoxCodeAndBackupTaskCode(null,backupTaskCode);
			if(!shippedBoxSkusLists.isEmpty()){
				for(ShippedBoxSkus s:shippedBoxSkusLists){
					if(sku.equals(s.getSkuId())){
						s.setRealQty(s.getRealQty()+1);
						shippedBoxSkusDao.save(s);
						fa=true;
						break;
					}
				}
			}
			//没有装箱就新增
			if(!fa){
				shippedBoxSkus=new ShippedBoxSkus();
				shippedBoxSkus.setSkuId(sku);
				shippedBoxSkus.setRealQty(1);
				shippedBoxSkus.setBatchCode(backupTaskCode);
				shippedBoxSkus.setBackupTaskCode(backupTaskCode);
				shippedBoxSkusDao.save(shippedBoxSkus);
			}
			
			backupTaskSku.setPickQty(indexNumber);
			backupTaskSkuDao.save(backupTaskSku);
		} catch (Exception e) {
			throw e;
		}
	}
	
	
	
	@Transactional(rollbackFor=Exception.class,readOnly = false)
	public ShippedBox excuteShippedBox(String backupTaskCode,String boxCode) throws Exception {
		ShippedBox shippedBox = null;
		List<ShippedBoxSkus> shippedBoxSkus = null;
		int skuQty = 0;
		try {
			BackupTask backupTask = backupTaskDao.findByBackupTaskCode(backupTaskCode);
			if("finish".equals(backupTask.getStatus())){
				return null;//该拣货任务封箱完毕
			}
			List<WorkTaskItem> workTaskItems=this.workTaskItemDao.loadByTaskCode(backupTaskCode);
			Map<String, Integer> allSkuMaps=new HashMap<String, Integer>();//已经拣货的sku汇总
			for(WorkTaskItem w:workTaskItems){
				String sku=w.getSku();
				int num=w.getPickedNum();
				if(num>0){
					if(allSkuMaps.get(sku)==null){
						allSkuMaps.put(sku, num);
					}else{
						allSkuMaps.put(sku, num+allSkuMaps.get(sku));
					}
				}
			}
			
			shippedBoxSkus=shippedBoxSkusDao.findByBackupTaskCode(backupTaskCode);
			Map<String, Integer> boxSkuMaps=new HashMap<String, Integer>();//已经装箱的sku汇总
			if(!shippedBoxSkus.isEmpty()){
				for(ShippedBoxSkus bs:shippedBoxSkus){
					String sku=bs.getSkuId();
					int num=bs.getRealQty();
					if(bs.getBoxCode()!=null){
						if(boxSkuMaps.get(sku)==null){
							boxSkuMaps.put(sku, num);
						}else{
							boxSkuMaps.put(sku, num+boxSkuMaps.get(sku));
						}
					}
				}
			}
			
			
			//得到未装箱的sku
			Map<String, Integer> noSkuMaps=new HashMap<String, Integer>();
			for(String allKey:allSkuMaps.keySet()){
				if(boxSkuMaps.get(allKey)==null){
					noSkuMaps.put(allKey, allSkuMaps.get(allKey));
				}else{
					if(allSkuMaps.get(allKey)>boxSkuMaps.get(allKey)){
						noSkuMaps.put(allKey, allSkuMaps.get(allKey)-boxSkuMaps.get(allKey));
					}
				}
			}
			if(noSkuMaps.isEmpty()){
				return null;
			}
			
			for(String noKey:noSkuMaps.keySet()){
				skuQty+=noSkuMaps.get(noKey);
				BackupTaskSku backupTaskSku=backupTaskSkuDao.findByBackupTaskCodeAndSkuId(backupTaskCode, noKey);
				int value=noSkuMaps.get(noKey)+backupTaskSku.getCheckQty();
				backupTaskSku.setCheckQty(value);
				if(value==backupTaskSku.getRealQty()){
					backupTaskSku.setPickStatus("finish");
				}else{
					backupTaskSku.setStatus("pending");
				}
				backupTaskSkuDao.save(backupTaskSku);
			}
			ShippedBatch shippedBatch = shippedBatchDao.findByBackupTaskCode(backupTaskCode);
			
			Date nowDate=new Date();
			for(String noKey:noSkuMaps.keySet()){
				ShippedBoxSkus obj=new ShippedBoxSkus();
				obj.setBackupTaskCode(backupTaskCode);
				obj.setBatchCode(backupTask.getBatchCode());
				obj.setBoxCode(boxCode);
				obj.setCheckQty(0);
				obj.setRealQty(noSkuMaps.get(noKey));
				obj.setSkuId(noKey);
				obj.setStatus("pending");
				obj.setUpdateDate(nowDate);
				this.shippedBoxSkusDao.save(obj);
			}
			
			shippedBox = new ShippedBox();
			shippedBox.setCreateDate(new Date());
			shippedBox.setUpdateDate(new Date());
			shippedBox.setBoxCode(boxCode);
			shippedBox.setSkuQty(skuQty);
			shippedBox.setStatus("pending");
			shippedBox.setType(shippedBatch.getType());
			shippedBox.setBatchCode(shippedBatch.getBatchCode());
			shippedBox.setSkuType(shippedBoxSkus.size());
			shippedBoxDao.save(shippedBox);
			shippedBatch.setBoxQty(shippedBatch.getBoxQty() + 1);// 箱子数量增加
			if ("finish".equals(backupTask.getPickStatus())) {
				shippedBatch.setBoxStatus("finish");
				backupTask.setStatus("finish");//完成装箱操作
				backupTaskDao.save(backupTask);
			}
			shippedBatchDao.save(shippedBatch);
		} catch (Exception e) {
			throw e;
		}
		return shippedBox;
	}
	
	/**
	 * 
	 * @param taskItemId 拣货任务项ID
	 * @param sku  sku编码
	 * 
	 * @return 'coutinue'    : 拣货成功,继续此任务项拣货
	 * @return 'finished' :  此任务项已完成
	 * @return 'finishing' :  拣货成功,此任务项完成
	 * @return 'task_finished' : 此任务已经完成
	 * @return 'task_finishing' : 拣货成功,此任务已经完成
	 * @return 'error'       : 验证不通过
	 * @throws Exception 
	 */
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public String pick(Long taskItemId, String sku,String pickType) throws Exception {
		try {
			
			WorkTaskItem item=this.workTaskItemDao.findOne(taskItemId);
			String taskCode=item.getTaskCode();
			BackupTask task=this.backupTaskDao.findByBackupTaskCode(taskCode);
			
			String msg="error";
			
			if(item==null || !item.getSku().equals(sku)){ //无此任务项,或者sku不匹配
				return "error"; 
			}
			
			if(item.getPickStatus().equals("picked")){ //任务项已经完成
				return "finished";
			}
			
			int num=item.getNum();
			int _pickedNum=item.getPickedNum();
			int pickedNum=_pickedNum+1;
			item.setPickedNum(pickedNum);
			
			
			if(_pickedNum==0){ //拣货成功,开始此任务项
				item.setPickStatus("picking");
				if(task.getStatus().equals("pending")){  
					//task.setStatus("working"); //任务状态:开始拣货任务
				}
			}
			
	        if(num>pickedNum){ //拣货成功,继续此任务项
	        	msg="coutinue";
			}else if(num==pickedNum){  //拣货成功,此任务项完成
				msg="finishing";
				item.setPickStatus("picked");
			}
	        
	        
			this.workTaskItemDao.save(item);
			task.setPickQty(task.getPickQty()+1);//已经拣货的数量
			this.backupTaskDao.save(task);
		/*	if("picking".equals(pickType)){//先拣货再装箱
				pickBackupTaskSku(task.getBackupTaskCode(),sku);//保留BMS集发状态
			}*/
			//查看同一任务的其它任务项是否都完成
			if(msg.equals("finishing")){
				Date now=new Date();
				List<WorkTaskItem> allItem=this.workTaskItemDao.loadUnPickItemByTaskCode(taskCode);
				if(allItem!=null && allItem.size()==0){ 
					
					//任务完成
				    msg="task_finishing";
			        task.setPickStatus("finish");
			        this.backupTaskDao.save(task);
			        Customers customer=this.customersDao.findByCustomerCode(task.getCustomerCode());
					if("1".equals(customer.getSubStock())){
						this.updateStock(task);//修改订单占用库存
					}
				    User user=this.userDao.findByJobuuid(task.getJobuuid());
				     
				    //作业日志
				    WorkLog workLog=new WorkLog(
				    		item.getBatchCode(),
				    		"4", //操作类型 (1.创建批次 2.创建任务 3.领取拣货任务  4.完成拣货任务 5.领取灯光拣选任务 6.完成灯光拣选任务  7.领取包装任务 8完成包装任务  9.领取发货任务  10.完成发货任务  11.打印单据 )
				    		"完成拣货任务("+item.getTaskCode()+")",
				    		now,
				    		user);
				    this.workLogDao.save(workLog);
				    
				    
				   //修改订单状态，添加日志
				   List<BackupTaskOrdeno> orderList=this.backupTaskOrdenoDao.findByBackupTaskCode(taskCode);
				   for (BackupTaskOrdeno order : orderList) {
					  order.setStatus("finish"); //订单状态 (1.创建拣货批次 2.创建拣货任务 3.已拣货 4.已包装 5.已发货 6.已签收 7.异常登记)
				   }
				   this.backupTaskOrdenoDao.save(orderList);
				    
				   //查看同一批次的其他任务是否完成，如果都完成，修改入库批次状态为：3
				   List<BackupTask> uncompletedTaskList=this.backupTaskDao.findByBatchCode(task.getBatchTaskCode());
				   if(uncompletedTaskList!=null && uncompletedTaskList.size()==0){
						BatchTask batch=this.batchTaskDao.findByBatchTaskCode(task.getBatchTaskCode());
						batch.setStatus("picking"); //批次状态 (pending.已创建批次 finish.已创建任务 picking.已拣货  )
						this.batchTaskDao.save(batch);
						
						//添加工作日志
						WorkLog workLog1=new WorkLog(
								task.getBatchCode(),
								"4",//操作类型 (1.创建批次 2.创建任务 3.领取拣货任务  4.完成拣货任务 5.领取灯光拣选任务 6.完成灯光拣选任务  7.领取包装任务 8完成包装任务  9.领取发货任务  10.完成发货任务   )
								"拣货任务全部完成", 
								now, 
								null);
						this.workLogDao.save(workLog1);
					}	 
				}
			}
			
			return msg;
		
		} catch (Exception e) {
			
			throw new Exception(e);
		}
		
		
		
		
	}

	private List<BackupTaskOrdeno> getBackupTaskOrdeno(Map<String, String> stockMap,Map<String, Integer> ranknoMap,String batchTaskCode) throws Exception {
		List<BackupTaskOrdeno> backupTaskOrdenos = new ArrayList<BackupTaskOrdeno>();

		try {
			for (String o : stockMap.keySet()) {
				BackupTaskOrdeno bt=backupTaskOrdenoDao.findByBatchTaskCodeAndOrdeno(batchTaskCode, o);
				bt.setStockInfo(stockMap.get(o));//库位信息
				bt.setRankno(ranknoMap.get(o));//顺序
				backupTaskOrdenos.add(bt);
			}
		} catch (Exception e) {
			throw e;
		}
		return backupTaskOrdenos;
	}
	
	@Transactional(rollbackFor = Exception.class, readOnly = false)
    private void createWorkTaskItem(List<BackupTaskOrdeno> backupTaskOrdenos,BackupTask backupTask)throws Exception{
    	List<WorkTaskItem> itemList=new ArrayList<WorkTaskItem>();
        try {
    		Map<String, Object> map=new LinkedHashMap<String, Object>();
    		List<Map.Entry<String,Object>> mapList=null;
        	//组合订单的取货信息
    		for (BackupTaskOrdeno order : backupTaskOrdenos) {
    			String stockInfo=order.getStockInfo();
    			String[] stockInfoSplit=stockInfo.split(";");
    			
    			for (String info : stockInfoSplit) {
    				try {
    					String[] infoSplit=info.split("_");
    					String stockCode=infoSplit[0];
    					String boxCode=infoSplit[1];
    					String sku=infoSplit[2];
    					String num=infoSplit[3];
    					String key=stockCode+"_"+boxCode+"_"+sku;
    					Integer value=Integer.valueOf(num);
    					if(map.containsKey(key)){
    						Integer temp=(Integer)map.get(key);
    						map.put(key, temp+value);
    					}else{
    						map.put(key, value);
    					}
    				} catch (Exception e) {
    					
    				}
    			}
    		}
    		
    		//按库位排序
    		mapList=new ArrayList<Map.Entry<String,Object>>(map.entrySet());
    		Collections.sort(mapList, new Comparator<Map.Entry<String,Object>>() {
    			@Override
    			public int compare(Entry<String, Object> o1,Entry<String, Object> o2) {
    				return o1.getKey().compareTo(o2.getKey());
    			}
    		});
    		//保存
    		int i=1;
            for (Entry<String, Object> entry : mapList) {
				
				String key=entry.getKey();
				Object value=entry.getValue();
				
				WorkTaskItem item=new WorkTaskItem();
				item.setBatchCode(backupTask.getBatchTaskCode());
				item.setTaskCode(backupTask.getBackupTaskCode());
				item.setCustomerCode(backupTask.getCustomerCode());
				item.setWarehouseCode(backupTask.getWarehouseCode());
				item.setPickStatus("unpicked");	//拣货状态（picked:已拣 unpicked:未拣）
				item.setPickedNum(0);
				String[] stockInfoSplit=key.split("_");
				String stockCode=stockInfoSplit[0];
				String boxCode=stockInfoSplit[1];
				String sku=stockInfoSplit[2];
				Integer num=(Integer)value;
				item.setOrderno("");
				item.setStockCode(stockCode);
				item.setBoxCode(boxCode);
				item.setSku(sku);
				item.setNum(num);
				item.setRankno(i);
				itemList.add(item);
				i++;
			}
			
			this.workTaskItemDao.save(itemList);
		  } catch (Exception e) {
		    
	   }
		  
		  
    }	
	
	@Transactional(rollbackFor = Exception.class, readOnly = false)
    private void createWorkTaskItem_1(List<BackupTaskOrdeno> backupTaskOrdenos,BackupTask backupTask)throws Exception{
    	List<WorkTaskItem> itemList=new ArrayList<WorkTaskItem>();
        try {
    		Map<String, Integer> map=new LinkedHashMap<String, Integer>();
        	//组合订单的取货信息
    		for (BackupTaskOrdeno order : backupTaskOrdenos) {
    			List<EdiOrderItem> ediOrderItems=this.ediOrderItemDao.findByCustomerCodeAndOrdeno(backupTask.getCustomerCode(), order.getOrdeno());
    			for(EdiOrderItem ei:ediOrderItems){
    				String key=ei.getSku();
    				if(map.containsKey(key)){
    					Integer temp=(Integer)map.get(key);
    					map.put(key, temp+ei.getQty());
    				}else{
    					map.put(key, ei.getQty());
    				}
    			}
				
    		}
    		
    		
    		//保存
    		int i=1;
            for (String key : map.keySet()) {
				Integer value=map.get(key);
				WorkTaskItem item=new WorkTaskItem();
				item.setBatchCode(backupTask.getBatchTaskCode());
				item.setTaskCode(backupTask.getBackupTaskCode());
				item.setCustomerCode(backupTask.getCustomerCode());
				item.setWarehouseCode(backupTask.getWarehouseCode());
				item.setPickStatus("unpicked");	//拣货状态（picked:已拣 unpicked:未拣）
				item.setPickedNum(0);
				item.setSku(key);
				item.setNum(value);
				item.setRankno(i);
				itemList.add(item);
				i++;
			}
			
			this.workTaskItemDao.save(itemList);
		  } catch (Exception e) {
		    
	   }
	}

	/**
	 * WMS生成拣货任务
	 * @param ordenos 订单号(:号分割)
	 * @param jobuuid
	 * @param batchTaskCode 分拣批次号
	 * @return
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public BackupTask createBachupTask(Map<String, String> stockMap,Map<String, Integer> ranknoMap, String batchTaskCode) throws Exception {
		BatchTask batchTask = batchTaskDao.findByBatchTaskCode(batchTaskCode);
		try {
			if(batchTask==null){
				throw new Exception(batchTaskCode+":该分拣批次不存在");
			}
			if ("finish".equals(batchTask.getStatus())) {
				throw new Exception(batchTaskCode+":该分拣批次已经完成分拣任务");
			}
			if ("working".equals(batchTask.getStatus())) {
				throw new Exception(batchTaskCode+":该分拣批次正在生成分拣任务中");
			}
			batchTask.setStatus("working");
			batchTaskDao.save(batchTask);
			List<BackupTaskOrdeno> backupTaskOrdenos=getBackupTaskOrdeno(stockMap,ranknoMap,batchTaskCode);
			BackupTask bt= createBachupTask(backupTaskOrdenos,batchTaskCode);
			createWorkTaskItem(backupTaskOrdenos,bt);//设置拣货
			setWMSSkuNumber(backupTaskOrdenos,bt);//减库存
			createShipped(bt);//创建出库批次
			List<BackupTaskOrdeno> lists=backupTaskOrdenoDao.findByBackupTaskCodeAndBatchTaskCode(null, batchTaskCode);
			if(lists.isEmpty()){
				batchTask.setStatus("finish");
				batchTaskDao.save(batchTask);
			}else{
				batchTask.setStatus("pending");
				batchTaskDao.save(batchTask);
			}
			return bt;
		} catch (Exception e) {
			batchTask.setStatus("pending");
			batchTaskDao.save(batchTask);
			throw e;
		}
	}
	
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public void setCusStockMerge(EdiOrder e){
		  
		 //如果是限制订单流入的商家，消除订单预定数量
		 Customers customer=this.customersDao.findByCustomerCode(e.getCustomerCode());
		 if("1".equals(customer.getPlaceStatus())){ //限制订单流入的商家
			
			//遍历订单，将订单的sku需求整理为：map<sku,num>格式 
			Map<String, Integer> map=new HashMap<String, Integer>();
				List<EdiOrderItem> itemList=this.ediOrderItemDao.findByOrdeno(e.getOrdeno());
				for (EdiOrderItem item : itemList) {
					String sku=item.getSku();
					int qty=item.getQty();
					if(map.keySet().contains(sku)){
						map.put(sku, map.get(sku)+qty);
					}else{
						map.put(sku, qty);
					}
				}
			 
			for(String sku: map.keySet()){
				int qty=map.get(sku);
				CusStockMerge merge=this.cusStockMergeDao.findCustomerWarSku(e.getCustomerCode(), e.getWarehouseCode(), sku);
				if(merge!=null){
					int _orderNum=merge.getOrderNum();
					int temp=_orderNum-qty;
					if (temp < 0) {
						log.error("预定库存异常，sku:"+sku+" ; 商家："+e.getCustomerCode()+" ; 仓库："+e.getWarehouseCode());
					}
					merge.setOrderNum(Math.max(temp,0));
					this.cusStockMergeDao.save(merge);
				}
			} 
			
		 }
	}
	
	/**
	 * WMS生成拣货任务_1
	 * @param ordenos 订单号(:号分割)
	 * @param jobuuid
	 * @param batchTaskCode 分拣批次号
	 * @return
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public BackupTask createBachupTask_1(Map<String, String> stockMap,Map<String, Integer> ranknoMap, String batchTaskCode) throws Exception {
		BatchTask batchTask = batchTaskDao.findByBatchTaskCode(batchTaskCode);
		try {
			if(batchTask==null){
				throw new Exception(batchTaskCode+":该分拣批次不存在");
			}
			if ("finish".equals(batchTask.getStatus())) {
				throw new Exception(batchTaskCode+":该分拣批次已经完成分拣任务");
			}
			if ("working".equals(batchTask.getStatus())) {
				throw new Exception(batchTaskCode+":该分拣批次正在生成分拣任务中");
			}
			batchTask.setStatus("working");
			batchTaskDao.save(batchTask);
			List<BackupTaskOrdeno> backupTaskOrdenos=getBackupTaskOrdeno(stockMap,ranknoMap,batchTaskCode);
			BackupTask bt= createBachupTask(backupTaskOrdenos,batchTaskCode);
			createWorkTaskItem_1(backupTaskOrdenos,bt);//设置拣货
			createShipped(bt);//创建出库批次
			List<BackupTaskOrdeno> lists=backupTaskOrdenoDao.findByBackupTaskCodeAndBatchTaskCode(null, batchTaskCode);
			if(lists.isEmpty()){
				batchTask.setStatus("finish");
				batchTaskDao.save(batchTask);
			}else{
				batchTask.setStatus("pending");
				batchTaskDao.save(batchTask);
			}
			return bt;
		} catch (Exception e) {
			batchTask.setStatus("pending");
			batchTaskDao.save(batchTask);
			throw e;
		}
	}
	
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	private void setWMSSkuNumber(List<BackupTaskOrdeno> backupTaskOrdenoLists,BackupTask bt) throws Exception {
		try {
			for (BackupTaskOrdeno e : backupTaskOrdenoLists) {
				    String pickStore=e.getStockInfo();
				    String picks[]=pickStore.split(";");
				    for(String p:picks){
				    	String[] stocks=p.split("_");
				        String stock=stocks[0];
				        String boxCode=stocks[1];
				        String sku=stocks[2];
				        int num=Integer.parseInt(stocks[3]);
				        //修改库存信息
						CusStock cusStock=this.cusStockDao.loadStock(bt.getCustomerCode(),bt.getWarehouseCode(),stock,boxCode,sku);
						cusStock.setSalesNum(cusStock.getSalesNum()-num);
						cusStock.setOrderNum(cusStock.getOrderNum()+num);
						this.cusStockDao.save(cusStock);
				    }
			     }
		} catch (Exception e) {
			throw e;
		}
	}
	
	
	private Map<String, BackupTaskSku> getMapsBackupTaskSkus(List<BackupTaskOrdeno> backupTaskOrdenoLists)throws Exception {
		Map<String, BackupTaskSku> backupTaskSkumaps = new HashMap<String, BackupTaskSku>();
		try {
			BatchTask batchTask=this.batchTaskDao.findByBatchTaskCode(backupTaskOrdenoLists.get(0).getBatchTaskCode());
			Customers customers=this.customersDao.findByCustomerCode(batchTask.getCustomerCode());
			if("1".equals(customers.getSubStock())){//减库存
			for(BackupTaskOrdeno b:backupTaskOrdenoLists){
				String pickStore=b.getStockInfo();
			    String picks[]=pickStore.split(";");
			    for(String p:picks){
			    	String[] stocks=p.split("_");
			        String stock=stocks[0];//库位
			        String boxCode=stocks[1];//箱子编码
			        String sku=stocks[2];//sku编码
			        int num=Integer.parseInt(stocks[3]);
			        BackupTaskSku value= backupTaskSkumaps.get(sku);
			        if(value==null){
			        	BackupTaskSku bts=new BackupTaskSku();
			        	bts.setSkuId(sku);
			        	bts.setStatus("pending");
			        	bts.setPickStatus("pending");
			        	bts.setRealQty(num);
			        	bts.setBackupTaskCode(b.getBackupTaskCode());
			        	bts.setBatchTaskCode(b.getBatchTaskCode());
			        	bts.setStockLists(stock+":"+boxCode+":"+num);
			        	EdiGoodsSku e= this.ediGoodsSkuDao.findByCustomerCodeAndSku( batchTask.getCustomerCode(), sku);
				        if(e!=null){
				        	 bts.setSkuName(e.getSkuName());
				         }
			        	backupTaskSkumaps.put(sku, bts);
			        }else{
			        	value.setRealQty(value.getRealQty()+num);
			        	String stockList=value.getStockLists();
			        	String[] lists=stockList.split(",");
			        	StringBuffer sb=new StringBuffer();
			        	for(String s:lists){
			        		String[] ss=s.split(":");
			        		if(stock.equals(ss[0])){//相同库位
			        			if(boxCode.equals(ss[1])){//相同箱子
			        				int i=num+Integer.parseInt(ss[2]);
			        				s=stock+":"+boxCode+":"+i;
			        			}
			        		 }
			              if("".equals(sb.toString())){
			            	  sb.append(s);
			              }else{
			            	  sb.append(","+s);
			              }
			        	}
			        	value.setStockLists(sb.toString());
			        }
			    }
			}
		 }else{
			 for(BackupTaskOrdeno b:backupTaskOrdenoLists){
				 List<EdiOrderItem> ediOrderItems=this.ediOrderItemDao.findByCustomerCodeAndOrdeno(customers.getCustomerCode(), b.getOrdeno());
				 for(EdiOrderItem ediOrderItem:ediOrderItems){
					 String sku=ediOrderItem.getSku();
					 BackupTaskSku value= backupTaskSkumaps.get(sku);
				        if(value==null){
				        	BackupTaskSku bts=new BackupTaskSku();
				        	bts.setSkuId(sku);
				        	bts.setStatus("pending");
				        	bts.setPickStatus("pending");
				        	bts.setRealQty(ediOrderItem.getQty());
				        	bts.setBackupTaskCode(b.getBackupTaskCode());
				        	bts.setBatchTaskCode(b.getBatchTaskCode());
				        	
				        	backupTaskSkumaps.put(sku, bts);
				        }else{
				        	value.setRealQty(value.getRealQty()+ediOrderItem.getQty());
				        }
				 }
			 }
			 for(String sku:backupTaskSkumaps.keySet()){
				 BackupTaskSku value= backupTaskSkumaps.get(sku);
				 List<CusStock> cusStocks=this.cusStockDao.loadStock(batchTask.getWarehouseCode(), batchTask.getCustomerCode(), sku);
		         if(cusStocks!=null&&!cusStocks.isEmpty()){
		        	 value.setStockLists(cusStocks.get(0).getStockCode()+":"+cusStocks.get(0).getBoxCode()+":"+value.getRealQty());
		         }
		         EdiGoodsSku e= this.ediGoodsSkuDao.findByCustomerCodeAndSku( batchTask.getCustomerCode(), sku);
		         if(e!=null){
		        	 value.setSkuName(e.getSkuName());
		         }
			 }
		 }
		} catch (Exception e) {
			
		}
		return backupTaskSkumaps;
	}
	
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public BackupTask createBachupTask(List<BackupTaskOrdeno> backupTaskOrdenoLists, String batchTaskCode) throws Exception {
		BackupTask backupTask = null;
		List<BackupTaskOrdeno> backupTaskOrdenos = null;
		int skuQty = 0;
		Map<String, BackupTaskSku> maps = null;
		BatchTask batchTask=batchTaskDao.findByBatchTaskCode(batchTaskCode);
		try {
			if (backupTaskOrdenoLists.isEmpty()) {
				return null;
			}
			DecimalFormat df=new DecimalFormat("0000000");
			backupTask = new BackupTask();// 拣货任务
			backupTask.setBatchType(batchTask.getBatchType());
			backupTask.setCreateDate(new Date());
			backupTask.setStatus("pending");
			backupTask.setType(batchTask.getType());
			backupTask.setUpdateDate(new Date());
			backupTask.setDate(batchTask.getDate());
			backupTask.setAreaGroupCode(batchTask.getAreaGroupCode());
			backupTask.setWarehouseCode(batchTask.getWarehouseCode());//客户仓库编码
			backupTask.setOrdenoQty(backupTaskOrdenoLists.size());
			backupTask.setCustomerCode(batchTask.getCustomerCode());
			backupTask.setBackupTaskCode("");
			backupTask.setBatchTaskCode(batchTask.getBatchTaskCode());
			backupTask.setJobuuid("pending");
			backupTask.setPickStatus("pending");// 标注拣货时候完成
			backupTask.setPickType("pending");
			backupTask.setPickQty(0);
			Date now=new Date();
            this.backupTaskDao.save(backupTask);
			String backupCode = "GB"+batchTask.getCustomerCode()+df.format(backupTask.getId());// 生成拣货编号
			backupTask.setBackupTaskCode(backupCode);
			ShiroUser curUser = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
			User user=this.userDao.findOne(curUser.id);
			backupTaskOrdenos = new ArrayList<BackupTaskOrdeno>();
			for (BackupTaskOrdeno backupTaskOrdeno : backupTaskOrdenoLists) {
				String ordeno = backupTaskOrdeno.getOrdeno();
				EdiOrder ediOrder = ediOrderDao.findByOrdeno(ordeno);
				if ("".equals(ediOrder.getBackupTaskCode())|| ediOrder.getBackupTaskCode() != null) {
					throw new Exception("该订单已经生成拣货任务:"+ ediOrder.getBackupTaskCode());
				}
				ediOrder.setBackupTaskCode(backupCode);
				ediOrderDao.save(ediOrder);
				setCusStockMerge(ediOrder);
				int ordenoSkuQty = 0;
				backupTaskOrdeno.setBackupTaskCode(backupTask.getBackupTaskCode());
				backupTaskOrdenos.add(backupTaskOrdeno);
				List<EdiOrderItem> ediOrderItems = ediOrderItemDao.findByOrdeno(ordeno);
				// 遍历订单商品信息获得一个拣货任务的所有sku信息
				for (EdiOrderItem ediOrderItem : ediOrderItems) {
					int qty = ediOrderItem.getQty();
					skuQty += qty;
					ordenoSkuQty += qty;
				}
				backupTaskOrdeno.setSkuQty(ordenoSkuQty);
				//添加订单日志
				OrderLog orderlog=new OrderLog(ordeno,
						batchTask.getCustomerCode(), 
						"2", //操作类型 （1.创建作业批次 2.创建作业任务 3.修正拣货信息 4.拣货完成 5.包装完成 6.发货完成 7.签收完成 8.异常登记）
						user,
						now,
						null, 
						user.getRealname()+"创建作业任务("+backupCode+")");
				this.orderLogDao.save(orderlog);
			}
			maps = getMapsBackupTaskSkus(backupTaskOrdenoLists);// 得到拣货信息
			backupTask.setSkuQty(skuQty);
			backupTask.setSkuType(maps.values().size());
			backupTaskOrdenoDao.save(backupTaskOrdenos);
			backupTaskSkuDao.save(maps.values());
			backupTaskDao.save(backupTask);
		} catch (Exception e) {
			throw e;
		}
		return backupTask;
	}


	public Map<String, Integer> getBackupTaskSku(List<BackupTask> backupTasks) {
		Map<String, Integer> maps = new HashMap<String, Integer>();
		for (BackupTask b : backupTasks) {
			List<BackupTaskSku> backupTaskSkus = backupTaskSkuDao
					.findByBackupTaskCode(b.getBackupTaskCode());
			for (BackupTaskSku bs : backupTaskSkus) {
				String sku = bs.getSkuId();
				int number = bs.getRealQty();
				Integer value = maps.get(sku);
				if (value == null) {
					maps.put(sku, number);
				} else {
					maps.put(sku, value + number);
				}
			}
		}
		return maps;
	}

	public List<BackupTask> findByStatusAndCustomerCode(String status,
			String customerCode) {
		return backupTaskDao.findByStatusAndCustomerCode(status, customerCode);
	}

	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public List<EdiOrder> getEdiOrder(String backupTaskCode, String jobuuid)
			throws Exception {
		List<EdiOrder> ediOrders = null;
		try {
			ediOrders = new ArrayList<EdiOrder>();
			BackupTask backupTask = backupTaskDao
					.findByBackupTaskCode(backupTaskCode);
			if (backupTask == null) {
				throw new Exception("该拣货批次编号不存在:" + backupTaskCode);
			}
			if (backupTask.getJobuuid() == null) {
				backupTask.setJobuuid(jobuuid);
				backupTaskDao.save(backupTask);
			}
			List<BackupTaskOrdeno> backupTaskOrdenos = backupTaskOrdenoDao
					.findByBackupTaskCode(backupTaskCode);
			if (backupTaskOrdenos.isEmpty()) {
				throw new Exception("该拣货批次订单数量为0:" + backupTaskCode);
			}
			for (BackupTaskOrdeno bt : backupTaskOrdenos) {
				ediOrders.add(ediOrderDao.findByOrdeno(bt.getOrdeno()));// 设置订单
			}
		} catch (Exception e) {
			throw e;
		}
		return ediOrders;
	}

	/**
	 * 分页显示表内所有行.
	 */
	public Page<BackupTask> getPageBackupTasks(
			Map<String, Object> filterParams, int pageNumber, int pageSize,
			String sortType) {
		PageRequest pageRequest = buildPageRequest(pageNumber, pageSize,
				sortType);
		Specification<BackupTask> spec = buildSpecification(filterParams);
		return backupTaskDao.findAll(spec, pageRequest);
	}

	/**
	 * 分页显示表内所有行.
	 */
	public Page<BackupTask> getPageBackupTasks(
			Map<String, Object> filterParams, int pageNumber, int pageSize,
			String sortType, Date fromDate, Date endDate) {
		PageRequest pageRequest = buildPageRequest(pageNumber, pageSize,
				sortType);
		Specification<BackupTask> spec = buildSpecification(filterParams,
				fromDate, endDate);
		return backupTaskDao.findAll(spec, pageRequest);
	}

	public List<BackupTask> getListBackupTasks(
			Map<String, Object> filterParams, Date fromDate, Date endDate) {

		Specification<BackupTask> spec = buildSpecification(filterParams,
				fromDate, endDate);
		return backupTaskDao.findAll(spec);
	}

	public List<BackupTask> getPageBackupTasks(Map<String, Object> filterParams) {

		Specification<BackupTask> spec = buildSpecification(filterParams);
		return backupTaskDao.findAll(spec);
	}

	public Page<BackupTask> getPageBackupTasks(int pageNumber, int pageSize,
			String sortType, Date fromDate, Date endDate, String type,
			String username, String customers, String areagroups) {
		PageRequest pageRequest = buildPageRequest(pageNumber, pageSize,
				sortType);
		Specification<BackupTask> spec = buildSpecification(fromDate, endDate,
				type, username, customers, areagroups);
		return backupTaskDao.findAll(spec, pageRequest);
	}

	private Specification<BackupTask> buildSpecification(final Date fromDate,
			final Date endDate, final String type, final String username,
			final String customers, final String areagroups) {
		return new Specification<BackupTask>() {
			@Override
			public Predicate toPredicate(Root<BackupTask> r,
					CriteriaQuery<?> q, CriteriaBuilder cb) {

				Predicate pre = cb.conjunction();
				if (StringUtils.isNotBlank(customers)) {
					String[] customerLists = customers.split(":");
					ComparisonPredicate[] tempCustomerCode = new ComparisonPredicate[customerLists.length];
					int i = 0;
					for (String customer : customerLists) {
						tempCustomerCode[i] = (ComparisonPredicate) cb.equal(
								r.get("customerCode"), customer);
						i++;
					}
					pre.getExpressions().add(cb.or(tempCustomerCode));
				}

				if (StringUtils.isNotBlank(areagroups)) {
					String[] areagroupLists = areagroups.split(":");
					ComparisonPredicate[] tempCustomerCode = new ComparisonPredicate[areagroupLists.length];
					int i = 0;
					for (String areagroup : areagroupLists) {
						tempCustomerCode[i] = (ComparisonPredicate) cb.equal(
								r.get("areaGroupCode"), areagroup);
						i++;
					}
					pre.getExpressions().add(cb.or(tempCustomerCode));
				}

				if (fromDate != null) {
					pre.getExpressions()
							.add(cb.greaterThan(r.<Date> get("createDate"),
									fromDate));
				}

				if (endDate != null) {
					pre.getExpressions().add(
							cb.lessThan(r.<Date> get("createDate"), endDate));
				}

				if (StringUtils.isNotBlank(username)) {
					pre.getExpressions().add(
							cb.like(r.<String> get("username"), username));

				}
				if (StringUtils.isNotBlank(type)) {
					pre.getExpressions().add(cb.equal(r.get("type"), type));

				}

				return pre;
			}

		};
	}

	/**
	 * 创建分页请求.
	 */
	private PageRequest buildPageRequest(int pageNumber, int pageSize,
			String sortType) {
		Sort sort = null;
		if (null != sortType) {
			if (sortType.endsWith("desc")) {
				sort = new Sort(Direction.DESC, "id");
			} else if (sortType.endsWith("asc")) {
				sort = new Sort(Direction.ASC, "id");
			}
		}
		return new PageRequest(pageNumber - 1, pageSize, sort);
	}

	private Specification<BackupTask> buildSpecification(
			Map<String, Object> filterParams, Date fromDate, Date endDate) {
		Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);
		filters.put("fromDate", new SearchFilter("createDate", Operator.GTE,
				fromDate));
		filters.put("toDate", new SearchFilter("createDate", Operator.LT,
				endDate));
		Specification<BackupTask> spec = DynamicSpecifications.bySearchFilter(
				filters.values(), BackupTask.class);
		return spec;
	}

	/**
	 * 创建动态查询条件组合.
	 */
	private Specification<BackupTask> buildSpecification(Map<String, Object> filterParams) {
		Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);
		Specification<BackupTask> spec = DynamicSpecifications.bySearchFilter(
				filters.values(), BackupTask.class);
		return spec;
	}

	public List<User> getAllUser() {
		List<User> users = (List<User>) userDao.findAll();
		for (User user : users) {
			List<Role> roles = roleDao.findByUserId(user.getId());
			user.setRoleList(roles);
		}
		return users;
	}

	public List<BackupTask> findByStatusAndJobuuid(String status, String jobuuid) {
		return backupTaskDao.findByStatusAndJobuuid(status, jobuuid);
	}

	public List<BackupTask> findByStatus(String status) {
		return backupTaskDao.findByStatus(status);
	}

	public List<BackupTask> findByPickStatus(String pickStatus) {
		return backupTaskDao.findByPickStatus(pickStatus);
	}

	public List<BackupTask> findBackupTaskStatus(final String customers,final String areagroups, final String status) {
		Specification<BackupTask> spec = buildSpecification(customers,areagroups, status);
		return backupTaskDao.findAll(spec);
	}

	private Specification<BackupTask> buildSpecification(
			final String customers, final String areagroups, final String status) {return new Specification<BackupTask>() {
			@Override
			public Predicate toPredicate(Root<BackupTask> r,CriteriaQuery<?> q, CriteriaBuilder cb) {

				Predicate pre = cb.conjunction();
				if (StringUtils.isNotBlank(customers)) {
					String[] customerLists = customers.split(":");
					ComparisonPredicate[] tempCustomerCode = new ComparisonPredicate[customerLists.length];
					int i = 0;
					for (String customer : customerLists) {
						tempCustomerCode[i] = (ComparisonPredicate) cb.equal(r.get("customerCode"), customer);
						i++;
					}
					pre.getExpressions().add(cb.or(tempCustomerCode));
				}

				if (StringUtils.isNotBlank(areagroups)) {
					String[] areagroupLists = areagroups.split(":");
					ComparisonPredicate[] tempCustomerCode = new ComparisonPredicate[areagroupLists.length];
					int i = 0;
					for (String areagroup : areagroupLists) {
						tempCustomerCode[i] = (ComparisonPredicate) cb.equal(r.get("areaGroupCode"), areagroup);
						i++;
					}
					pre.getExpressions().add(cb.or(tempCustomerCode));
				}

				if (StringUtils.isNotBlank(status)) {
					pre.getExpressions().add(cb.equal(r.get("status"), status));
				}

				return pre;
			}

		};
	}
	
	public List<BackupTask> findBackupTaskStatus(final String customers,final String areagroups, final String status,final String jobuuid) {
		Specification<BackupTask> spec = buildSpecification(customers,areagroups, status,jobuuid);
		return backupTaskDao.findAll(spec);
	}

	private Specification<BackupTask> buildSpecification(
			final String customers, final String areagroups, final String status,final String jobuuid) {return new Specification<BackupTask>() {
			@Override
			public Predicate toPredicate(Root<BackupTask> r,CriteriaQuery<?> q, CriteriaBuilder cb) {

				Predicate pre = cb.conjunction();
				if (StringUtils.isNotBlank(customers)) {
					String[] customerLists = customers.split(":");
					ComparisonPredicate[] tempCustomerCode = new ComparisonPredicate[customerLists.length];
					int i = 0;
					for (String customer : customerLists) {
						tempCustomerCode[i] = (ComparisonPredicate) cb.equal(r.get("customerCode"), customer);
						i++;
					}
					pre.getExpressions().add(cb.or(tempCustomerCode));
				}

				if (StringUtils.isNotBlank(areagroups)) {
					String[] areagroupLists = areagroups.split(":");
					ComparisonPredicate[] tempCustomerCode = new ComparisonPredicate[areagroupLists.length];
					int i = 0;
					for (String areagroup : areagroupLists) {
						tempCustomerCode[i] = (ComparisonPredicate) cb.equal(r.get("areaGroupCode"), areagroup);
						i++;
					}
					pre.getExpressions().add(cb.or(tempCustomerCode));
				}

				if (StringUtils.isNotBlank(status)) {
					pre.getExpressions().add(cb.equal(r.get("status"), status));
				}
				if (StringUtils.isNotBlank(jobuuid)) {
					pre.getExpressions().add(cb.equal(r.get("jobuuid"), jobuuid));
				}

				return pre;
			}

		};
	}
	
   public Page<BackupTask> findBackupTaskStatus(int pageNumber, int pageSize,String sortType,final Map<String, Object> param) {
	    PageRequest pageRequest=buildPageRequest(pageNumber, pageSize, sortType);
		Specification<BackupTask> spec = buildSpecificationNew(param);
		return backupTaskDao.findAll(spec, pageRequest);
	}
	
	public List<BackupTask> findBackupTaskStatus(final Map<String, Object> param) {
		
		Specification<BackupTask> spec = buildSpecificationNew(param);
		List<BackupTask> backupTasks=backupTaskDao.findAll(spec);
		if(backupTasks!=null){
			for(BackupTask b:backupTasks){
				b.setBoxQty(this.shippedBatchDao.findByBackupTaskCode(b.getBackupTaskCode()).getBoxQty());
			}
		}
		return backupTasks;
	}

	private Specification<BackupTask> buildSpecificationNew(final Map<String, Object> param) {return new Specification<BackupTask>() {
			@Override
			public Predicate toPredicate(Root<BackupTask> r,CriteriaQuery<?> q, CriteriaBuilder cb) {

				Predicate pre = cb.conjunction();
				String customers=(String)param.get("customers");//商家编码列表
				
				if (StringUtils.isNotBlank(customers)) {
					String[] customerLists = customers.split(":");
					ComparisonPredicate[] tempCustomerCode = new ComparisonPredicate[customerLists.length];
					int i = 0;
					for (String customer : customerLists) {
						tempCustomerCode[i] = (ComparisonPredicate) cb.equal(r.get("customerCode"), customer);
						i++;
					}
					pre.getExpressions().add(cb.or(tempCustomerCode));
				}

				String areagroups=(String)param.get("areagroups");//网点列表
				if (StringUtils.isNotBlank(areagroups)) {
					String[] areagroupLists = areagroups.split(":");
					ComparisonPredicate[] tempCustomerCode = new ComparisonPredicate[areagroupLists.length];
					int i = 0;
					for (String areagroup : areagroupLists) {
						tempCustomerCode[i] = (ComparisonPredicate) cb.equal(r.get("areaGroupCode"), areagroup);
						i++;
					}
					pre.getExpressions().add(cb.or(tempCustomerCode));
				}

				String status=(String)param.get("status");//装箱状态
				if (StringUtils.isNotBlank(status)) {
					pre.getExpressions().add(cb.equal(r.get("status"), status));
				}
				
				String batchType=(String)param.get("batchType");
				if (StringUtils.isNotBlank(batchType)) {
					pre.getExpressions().add(cb.equal(r.get("type"), batchType));
				}
				
				String pickStatus=(String)param.get("pickStatus");//拣货状态
				if (StringUtils.isNotBlank(pickStatus)) {
					pre.getExpressions().add(cb.equal(r.get("pickStatus"), pickStatus));
				}
				
				String jobuuids=(String)param.get("jobuuid");//任务领取状态
				if (StringUtils.isNotBlank(jobuuids)) {
					String[] jobuuid = jobuuids.split(":");
					ComparisonPredicate[] tempJobuuid = new ComparisonPredicate[jobuuid.length];
					int i = 0;
					for (String pt : jobuuid) {
						tempJobuuid[i] = (ComparisonPredicate) cb.equal(r.get("jobuuid"), pt);
						i++;
					}
					pre.getExpressions().add(cb.or(tempJobuuid));
				}
				
				String pickTypes=(String)param.get("pickType");//拣货类型
				if (StringUtils.isNotBlank(pickTypes)) {
					String[] pickType = pickTypes.split(":");
					ComparisonPredicate[] tempPickType = new ComparisonPredicate[pickType.length];
					int i = 0;
					for (String pt : pickType) {
						tempPickType[i] = (ComparisonPredicate) cb.equal(r.get("pickType"), pt);
						i++;
					}
					pre.getExpressions().add(cb.or(tempPickType));
				
				}
				
				 Date fromDate= (Date) param.get("fromDate");
			      if (fromDate != null) {
			        pre.getExpressions().add(cb.greaterThanOrEqualTo(r.<Date>get("createDate"), fromDate));
			      }
			      
			      Date toDate= (Date) param.get("toDate");
			      if (toDate != null) {
			        pre.getExpressions().add(cb.lessThanOrEqualTo(r.<Date>get("createDate"), toDate));
			      }
			      
			      String warehouseCode=(String) param.get("warehouseCode");
			    
			      if (StringUtils.isNotBlank(warehouseCode)) {
						String[] customerLists = warehouseCode.split(":");
						ComparisonPredicate[] tempCustomerCode = new ComparisonPredicate[customerLists.length];
						int i = 0;
						for (String customer : customerLists) {
							tempCustomerCode[i] = (ComparisonPredicate) cb.equal(r.get("warehouseCode"), customer);
							i++;
						}
						pre.getExpressions().add(cb.or(tempCustomerCode));
					}
			      
			      String areaGroupCode=(String) param.get("areaGroupCode");
			      if(StringUtils.isNotEmpty(areaGroupCode)){
			    	  pre.getExpressions().add(cb.equal(r.get("areaGroupCode"),areaGroupCode));
			      }

				return pre;
			}

		};
	}

	public List<BackupTask> findByPickStatusAndJobuuid(String pickStatus,
			String jobuuid) {
		return backupTaskDao.findByPickStatusAndJobuuid(pickStatus, jobuuid);
	}

	@Transactional(readOnly = false)
	public BackupTask save(BackupTask arg0) {
		return backupTaskDao.save(arg0);
	}

	@Transactional(readOnly = false)
	public List<BackupTask> save(List<BackupTask> arg0) {
		return (List<BackupTask>) backupTaskDao.save(arg0);
	}


	public BackupTask findByBackupTaskCode(String backupTaskCode) {
		ShippedBatch shippedBatch=this.shippedBatchDao.findByBackupTaskCode(backupTaskCode);
		BackupTask backupTask=backupTaskDao.findByBackupTaskCode(backupTaskCode);
		backupTask.setBoxQty(shippedBatch.getBoxQty());
		return backupTask;
	}

	public List<GroupBackupTaskDTO> getGroupBackupTasks(String batchTaskCode,
			int number, String customerCode) {
		List<GroupBackupTaskDTO> groupBackupTaskDTOs = new ArrayList<GroupBackupTaskDTO>();
		List<BackupTaskOrdeno> backupTaskOrdenos = backupTaskOrdenoDao
				.findByBatchTaskCode(batchTaskCode);
		if (backupTaskOrdenos.isEmpty()) {
			return null;
		}
		int length = backupTaskOrdenos.size();// 总长度
		int pageCount = length % number == 0 ? length / number : length
				/ number + 1;// 页数
		for (int i = 0; i < pageCount; i++) {
			int fromIndex = i * number;
			int toIndex = (i + 1) * number > length ? length : (i + 1) * number;
			GroupBackupTaskDTO groupBackupTaskDTO = new GroupBackupTaskDTO();
			groupBackupTaskDTO.setGroupOrdenos(fromIndex + "~" + toIndex);
			groupBackupTaskDTO.setUserDTOs(getUserDTOs(customerCode));
			groupBackupTaskDTOs.add(groupBackupTaskDTO);
		}
		return groupBackupTaskDTOs;
	}

	private List<UserDTO> getUserDTOs(String customerCode) {
		List<UserDTO> userDTOs = new ArrayList<UserDTO>();
		List<User> users = (List<User>) userDao
				.findByCustomerCode(customerCode);
		for (User user : users) {
			UserDTO userDTO = new UserDTO();
			userDTO.setUsername(user.getRealname());
			userDTO.setJobuuid(user.getJobuuid());
			userDTOs.add(userDTO);
		}
		return userDTOs;
	}

	public List<BackupTask> findByCreateDateBetween(Date startDate, Date endDate) {
		return backupTaskDao.findByCreateDateBetween(startDate, endDate);
	}


	/**
	 * 统计一个拣货任务的所有商品种类与数量
	 * 
	 * @param backupTaskOrdenoLists
	 * @param areagroupCode
	 * @param customerCode
	 * @return
	 * @throws Exception
	 */
	private Map<String, Integer> getSkuMaps(
			List<BackupTaskOrdeno> backupTaskOrdenoLists, String areagroupCode,
			String customerCode) throws Exception {
		Map<String, Integer> maps = new HashMap<String, Integer>();
		try {
			for (BackupTaskOrdeno e : backupTaskOrdenoLists) {
				List<EdiOrderItem> eis = ediOrderItemDao
						.findByCustomerCodeAndOrdeno(customerCode,
								e.getOrdeno());
				for (EdiOrderItem ei : eis) {
					if (maps.get(ei.getSku()) == null) {
						maps.put(ei.getSku(), ei.getQty());
					} else {
						maps.put(ei.getSku(),
								ei.getQty() + maps.get(ei.getSku()));
					}
				}
			}
		} catch (Exception e) {
			throw e;
		}
		return maps;
	}

	

	
	private void getEdiOrderItems(Map<String, StockSku> maps,
			List<EdiOrderItem> ediOrderItems) throws Exception {
		try {
			for (EdiOrderItem e : ediOrderItems) {
				StockSku s = null;
				if (maps.get(e.getSku()) == null) {
					s = new StockSku();
					s.setNumber(e.getQty());

				} else {
					s = maps.get(e.getSku());
					s.setNumber(s.getNumber() + e.getQty());
				}
				maps.put(e.getSku(), s);
			}
		} catch (Exception e) {
			throw e;
		}
	}

	private Map<String, StockSku> getStockSkus(
			List<BackupTaskOrdeno> backupTaskOrdenoLists, String customerCode,
			String batchType) throws Exception {
		Map<String, StockSku> maps = new HashMap<String, StockSku>();
		try {
			for (BackupTaskOrdeno e : backupTaskOrdenoLists) {
				String ordeno = e.getOrdeno();
				if (StatusEnums.ZWAREHOUSE.getStatus().equals(batchType)) {
					List<EdiOrderItem> ediOrderItems = ediOrderItemDao.findByCustomerCodeAndOrdeno(customerCode, ordeno);
					getEdiOrderItems(maps, ediOrderItems);
				} else if (StatusEnums.FWAREHOUSE.getStatus().equals(batchType)) {
					EdiOrder ediOrder = ediOrderDao.findByOrdeno(ordeno);
					String pickStore = ediOrder.getPickStore();
					String[] keys = pickStore.split(",");
					for (String s : keys) {
						String[] values = s.split(":");
						if (values.length != 3) {
							throw new Exception("生成拣货任务失败");
						}
						String store = values[0];
						String sku = values[1];
						String qty = values[2];
						int indexQty = Integer.parseInt(qty);
						setMaps(maps, sku, store, indexQty);
					}
				}
			}
		} catch (Exception e) {
			throw e;
		}
		return maps;
	}

	private void setMaps(Map<String, StockSku> maps, String key,
			String stockCode, int qty) throws Exception {
		try {
			StockSku value = maps.get(key);
			if (value == null) {
				StockSku s = new StockSku();
				s.setNumber(qty);
				s.setStockList(stockCode + ":" + qty);
				maps.put(key, s);
				return;
			}
			value.setNumber(value.getNumber() + qty);
			String[] keys = value.getStockList().split(",");// 库位编号:数量,库位编号:数量
			StringBuffer sb = new StringBuffer();
			boolean fa = true;
			for (String k : keys) {
				String[] temps = k.split(":");
				if (stockCode.equals(temps[0])) {
					qty += Integer.parseInt(temps[1]);
					k = temps[0] + ":" + qty;
					fa = false;
				}
				if ("".equals(sb.toString())) {
					sb.append(k);
				} else {
					sb.append("," + k);
				}
			}
			if (fa) {
				sb.append("," + stockCode + ":" + qty);
			}
			value.setStockList(sb.toString());
			maps.put(key, value);
		} catch (Exception e) {
			throw e;
		}
	}


	/**
	 * 一键拣货
	 * 
	 * @param backupTaskCode
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public String pickBackupTaskSku(String backupTaskCode) throws Exception {
		try {
			BackupTask backupTask = backupTaskDao.findByBackupTaskCode(backupTaskCode);
			if (backupTask == null) {
				return "该拣货任务不存在";
			}
			if ("finish".equals(backupTask.getPickStatus())) {
				return "该拣货任务已经完成拣货";
			}
			List<BackupTaskSku> backupTaskSkus=this.backupTaskSkuDao.findByBackupTaskCodeAndPickStatus(backupTaskCode, "pending");
			for(BackupTaskSku b:backupTaskSkus){
				b.setPickQty(b.getRealQty());
				b.setPickStatus("finish");
			}
			this.backupTaskSkuDao.save(backupTaskSkus);
			
			List<WorkTaskItem> wtis=this.workTaskItemDao.findByTaskCode(backupTaskCode);
			for(WorkTaskItem w:wtis){
				w.setPickedNum(w.getNum());
				w.setPickStatus("picked");
			}
			this.workTaskItemDao.save(wtis);
			Customers customer=this.customersDao.findByCustomerCode(backupTask.getCustomerCode());
			if("1".equals(customer.getSubStock())){
				this.updateStock(backupTask);//修改订单占用库存
			}
			backupTask.setPickStatus("finish");
			backupTaskDao.save(backupTask);
			return "拣货成功";
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * 获得打印的信息
	 * 
	 * @param ordenos
	 * @param customers
	 * @param backupTaskCode
	 * @return
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public List<PrintEdiOrdeno> getPrintEdiOrdeno(String ordenos,
			Customers customers, String backupTaskCode) throws Exception {
		List<PrintEdiOrdeno> printEdiOrdenos = new ArrayList<PrintEdiOrdeno>();
		BackupTask backupTask = null;
		List<BackupTaskOrdeno> backupTaskOrdenos = null;
		BatchTask batchTask = null;
		try {
			backupTask = backupTaskDao.findByBackupTaskCode(backupTaskCode);
			if (backupTask == null) {
				throw new Exception(backupTaskCode + "该打印任务不存在");
			}
			batchTask = batchTaskDao.findByBatchTaskCode(backupTask
					.getBatchTaskCode());
			String[] ordenoList = ordenos.split(":");
			for (String o : ordenoList) {
				EdiOrder e = ediOrderDao.findByOrdeno(o);
				if (e != null) {
					BackupTaskOrdeno backupTaskOrdeno = backupTaskOrdenoDao
							.findByOrdeno(o);
					if (backupTaskOrdeno == null) {
						throw new Exception(o + "订单信息有误");
					}
					if (!"finish".equals(backupTaskOrdeno.getStatus())) {
						backupTaskOrdeno.setStatus("finish");
						backupTaskOrdenoDao.save(backupTaskOrdeno);
					}
					PrintEdiOrdeno p = new PrintEdiOrdeno();
					p.setActuallyPaid(e.getActuallyPaid() + "");
					p.setAddres(e.getAddres());
					p.setCityco(e.getCityco());
					p.setCityna(e.getCityna());
					p.setCustomerName(customers.getCustomerName());
					p.setMessage(e.getShmemo());
					p.setMobile(e.getMobile());
					p.setOrdeno(e.getOrdeno());
					p.setProvco(e.getProvco());
					p.setProvna(e.getProvna());
					p.setRecena(e.getRecena());
					p.setSkuQty(e.getSkuQty() + "");
					p.setTeleph(e.getTeleph());
					p.setAreaGroupName(batchTask.getAreaGroupName());
					p.setWaybillNo(e.getWaybillNo());

					// 商品明细
					List<PrintEdiOrdenoItem> printEdiOrdenoItems = new ArrayList<PrintEdiOrdenoItem>();
					List<EdiOrderItem> ediOrderItems = ediOrderItemDao
							.findByOrdeno(o);
					for (EdiOrderItem eio : ediOrderItems) {
						PrintEdiOrdenoItem pei = new PrintEdiOrdenoItem();
						pei.setAmo(eio.getAmo());
						pei.setCol(eio.getCol());
						pei.setDis(eio.getDis());
						pei.setNam(eio.getNam());
						pei.setPay(eio.getPay());
						pei.setPri(eio.getPri());
						pei.setPro(eio.getPro());
						pei.setQty(eio.getQty());
						pei.setSiz(eio.getSiz());
						pei.setSku(eio.getSku());
						pei.setStoreCode(eio.getStoreCode());
						pei.setTdSkuId(eio.getTdSkuId());
						printEdiOrdenoItems.add(pei);
					}
					p.setPrintEdiOrdenoItem(printEdiOrdenoItems);
					printEdiOrdenos.add(p);
				}
			}
			backupTaskOrdenos = backupTaskOrdenoDao
					.findByBackupTaskCodeAndStatus(backupTaskCode, "pending");
			if (backupTaskOrdenos.isEmpty()) {
				createShipped(backupTask);
			}
		} catch (Exception e) {
			throw e;
		}
		return printEdiOrdenos;
	}

	/**
	 * 创建出库批次
	 * 
	 * @param backupTask
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	private void createShipped(BackupTask backupTask) throws Exception {

		try {
			ShippedBatch shippedBatch = shippedBatchDao.findByBackupTaskCode(backupTask.getBackupTaskCode());
			if (shippedBatch != null) {
				return;
			}
			shippedBatch = new ShippedBatch();// 出库批次
			Date nowDate = new Date();
			backupTask.setBatchCode(backupTask.getBackupTaskCode());
			shippedBatch.setBackupTaskCode(backupTask.getBackupTaskCode());
			shippedBatch.setBatchCode(backupTask.getBackupTaskCode());
			shippedBatch.setCreateDate(nowDate);
			shippedBatch.setJobuuid(backupTask.getJobuuid());
			shippedBatch.setCustomerCode(backupTask.getCustomerCode());
			shippedBatch.setType(backupTask.getType());
			shippedBatch.setWarehouseCode(backupTask.getWarehouseCode());
			shippedBatch.setUpdateDate(nowDate);
			List<BackupTaskOrdeno> backupTaskOrdenos = backupTaskOrdenoDao.findByBackupTaskCode(backupTask.getBackupTaskCode());
			for (BackupTaskOrdeno bto : backupTaskOrdenos) {
				EdiOrder ediOrder = ediOrderDao.findByOrdeno(bto.getOrdeno());
				ediOrder.setBatchCode(backupTask.getBackupTaskCode());
				ediOrderDao.save(ediOrder);
				ShippedBoxOrdeno shippedBoxOrdeno = new ShippedBoxOrdeno();
				shippedBoxOrdeno.setBatchCode(backupTask.getBackupTaskCode());
				shippedBoxOrdeno.setOrdeno(bto.getOrdeno());
				shippedBoxOrdeno.setWaybillNo(bto.getWaybillNo());
				shippedBoxOrdeno.setCrtime(nowDate);
				shippedBoxOrdeno.setStatus("pending");
				shippedBoxOrdenoDao.save(shippedBoxOrdeno);
			}
			shippedBatch.setAreaGroupCode(backupTask.getAreaGroupCode());
			shippedBatch.setOrdenoQty(backupTaskOrdenos.size());
			shippedBatch.setUsername(backupTask.getUsername());
			shippedBatch.setStatus("pending");
			shippedBatch.setBoxStatus("pending");// 表示是否已经装箱完成
			shippedBatch.setBatchType(backupTask.getBatchType());
			shippedBatch.setSkuQty(backupTask.getSkuQty());
			shippedBatch.setSkuType(backupTask.getSkuType());
			shippedBatch.setJobuuid("pending");
			backupTaskDao.save(backupTask);
			shippedBatchDao.save(shippedBatch);
			for (BackupTaskOrdeno obj : backupTaskOrdenos) {
				obj.setBatchCode(backupTask.getBackupTaskCode());
				backupTaskOrdenoDao.save(obj);
			}
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * 任务拣货
	 * 
	 * @param backupTaskCode
	 * @param sku
	 * @param number
	 * @return
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public BackupTaskSkuDTO pickBackupTaskSku(
			String backupTaskCode, String sku, int number) throws Exception {
		try {
			BackupTask backupTask = backupTaskDao.findByBackupTaskCode(backupTaskCode);
			if (backupTask == null) {
				return null;
			}
			BackupTaskSku backupTaskSku = backupTaskSkuDao.findByBackupTaskCodeAndSkuId(backupTaskCode, sku);
			if (backupTaskSku == null) {
				return null;
			}
			BackupTaskSkuDTO backupTaskSkuDTO = BeanMapper.map(backupTaskSku,BackupTaskSkuDTO.class);
			if ("finish".equals(backupTask.getPickStatus())) {
				backupTaskSkuDTO.setStatus("-1");
				backupTaskSkuDTO.setReserve("该拣货任务已经拣货");
				return backupTaskSkuDTO;
			}
			int indexNumber = number + backupTaskSku.getPickQty();
			if (indexNumber > backupTaskSku.getRealQty()) {
				backupTaskSkuDTO.setStatus("-1");
				backupTaskSkuDTO.setReserve("拣货失败:请核对商品数量：该商品实际数量为:" + backupTaskSku.getRealQty() + "---已拣货数量为:" + backupTaskSku.getPickQty());
				return backupTaskSkuDTO;
			}
			if (backupTaskSku.getRealQty() == indexNumber) {
				backupTaskSku.setPickStatus("finish");
				backupTaskSkuDTO.setReserve("拣货成功：该商品已经拣货完成");
			} else {
				backupTaskSku.setPickStatus("pending");
				backupTaskSkuDTO.setReserve("拣货成功：该商品还剩余商品:" + (backupTaskSku.getRealQty() - indexNumber) + "件");
			}
			backupTaskSku.setPickQty(indexNumber);
			backupTaskSkuDao.save(backupTaskSku);
			backupTask.setPickQty(backupTask.getPickQty()+number);
			this.backupTaskDao.save(backupTask);
			List<BackupTaskSku> backupTaskSkus = backupTaskSkuDao.findByBackupTaskCodeAndPickStatus(backupTaskCode, "pending");
			if (backupTaskSkus.isEmpty()) {
				Customers customer=this.customersDao.findByCustomerCode(backupTask.getCustomerCode());
				if("1".equals(customer.getSubStock())){
					this.updateStock(backupTask);//修改订单占用库存
				}
				backupTask.setPickStatus("finish");
				backupTaskDao.save(backupTask);
				backupTaskSkuDTO.setReserve("拣货成功：拣货批次已经拣货完成");
			}
			return backupTaskSkuDTO;
		} catch (Exception e) {
			throw e;
		}
	}

	

	
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public BackupTask createBachupTaskHT(
			List<BackupTaskOrdeno> backupTaskOrdenoLists, String jobuuid,
			BatchTask batchTask) throws Exception {
		BackupTask backupTask = null;
		List<BackupTaskOrdeno> backupTaskOrdenos = null;
		Map<String, BackupTaskSku> backupTaskSkus = null;
		int skuQty = 0;
		try {
			if (backupTaskOrdenoLists.isEmpty()) {
				return null;
			}
			User user = userDao.findByJobuuid(jobuuid);
			backupTask = new BackupTask();// 拣货任务
			String backupCode = BackupTaskRule.getBackupTaskCode(batchTask
					.getBatchTaskCode());// 生成拣货编号

			backupTask.setCreateDate(new Date());
			backupTask.setJobuuid(jobuuid);
			backupTask.setStatus("pending");
			backupTask.setType(batchTask.getType());
			backupTask.setUpdateDate(new Date());
			backupTask.setDate(batchTask.getDate());
			backupTask.setAreaGroupCode(batchTask.getAreaGroupCode());
			backupTask.setOrdenoQty(backupTaskOrdenoLists.size());
			backupTask.setBackupTaskCode(backupCode);
			backupTask.setBatchTaskCode(batchTask.getBatchTaskCode());
			if (user != null) {
				backupTask.setUsername(user.getRealname());
			}

			backupTask.setPickStatus("pending");// 标注拣货时候完成

			backupTaskOrdenos = new ArrayList<BackupTaskOrdeno>();
			backupTaskSkus = new HashMap<String, BackupTaskSku>();
			for (BackupTaskOrdeno backupTaskOrdeno : backupTaskOrdenoLists) {
				String ordeno = backupTaskOrdeno.getOrdeno();
				int ordenoSkuQty = 0;
				backupTaskOrdeno.setBackupTaskCode(backupTask
						.getBackupTaskCode());
				backupTaskOrdenos.add(backupTaskOrdeno);
				List<EdiOrderItem> ediOrderItems = ediOrderItemDao
						.findByOrdeno(ordeno);
				// 遍历订单商品信息获得一个拣货任务的所有sku信息
				for (EdiOrderItem ediOrderItem : ediOrderItems) {
					String sku = ediOrderItem.getSku();
					int qty = ediOrderItem.getQty();
					BackupTaskSku backupTaskSku = null;
					boolean fa = ediOrderItem.getCom();
					if (fa) {
						while (qty > 0) {
							String skuLists = ediOrderItem.getSkulist();
							String[] lists = skuLists.split(",");
							for (String skuList : lists) {
								String[] values = skuList.split(":");
								String s = values[0];// sku
								int q = Integer.parseInt(values[1]);// 数量
								skuQty += q;// 统计数量
								ordenoSkuQty += q;
								backupTaskSku = backupTaskSkus.get(s);
								if (backupTaskSku == null) {
									backupTaskSku = new BackupTaskSku();
									backupTaskSku.setSkuId(s);
									backupTaskSku.setStatus("pending");
									backupTaskSku.setPickStatus("pending");
									backupTaskSku.setRealQty(q);
									backupTaskSku.setBackupTaskCode(backupTask
											.getBackupTaskCode());
									backupTaskSkus.put(s, backupTaskSku);

								} else {
									backupTaskSku.setRealQty(backupTaskSku
											.getRealQty() + q);
								}
							}
							qty--;
						}

						continue;
					}
					backupTaskSku = backupTaskSkus.get(sku);
					skuQty += qty;
					ordenoSkuQty += qty;
					if (backupTaskSku == null) {
						backupTaskSku = new BackupTaskSku();
						backupTaskSku.setSkuId(ediOrderItem.getSku());
						backupTaskSku.setStatus("pending");
						backupTaskSku.setRealQty(qty);
						backupTaskSku.setPickStatus("pending");
						backupTaskSku.setBackupTaskCode(backupTask
								.getBackupTaskCode());
						backupTaskSkus.put(sku, backupTaskSku);
					} else {
						backupTaskSku.setRealQty(backupTaskSku.getRealQty()
								+ qty);
					}
				}
				backupTaskOrdeno.setSkuQty(ordenoSkuQty);
			}
			backupTask.setSkuQty(skuQty);
			backupTask.setSkuType(backupTaskSkus.values().size());
			backupTaskOrdenoDao.save(backupTaskOrdenos);
			backupTaskSkuDao.save(backupTaskSkus.values());
			backupTaskDao.save(backupTask);

		} catch (Exception e) {
			throw e;
		}
		return backupTask;
	}

	/**
	 * 查询任务
	 * @param batchCode 批次编号
	 * @return
	 */
	public List<BackupTask> findbyBatchCode(String batchCode) {
		return this.backupTaskDao.findByBatchCode(batchCode);
	}

}
